home *** CD-ROM | disk | FTP | other *** search
/ Revolution - Das Atari CD Magazin 1997 / Revolution - Das Atari CD Magazin 1.iso / software / anwendng / qed_397 / sourcen / file.c < prev    next >
C/C++ Source or Header  |  1997-01-07  |  11KB  |  555 lines

  1. /*
  2.  * file.c
  3.  *
  4.  * Da mir die ursprünlichen Lese/Schreib-Routinen viel zu undurchschaubar waren
  5.  * und ich z.B. kein Mac-Zeilenende nachrüsten konnte, habe ich eigene, deutlich
  6.  * einfachere Funktionen definiert.
  7.  * Die Methode mit dem 'if else if' beim Einlesen ist sicherlich nicht die
  8.  * schnellste, aber sie funktioniert und ist sehr übersichtlich :-)
  9.  * Auf dem TT gibt es keine bermerkbaren Geschwindigkeitsverluste!
  10. */
  11. #include <errno.h>
  12.  
  13. #include "global.h"
  14. #include "comm.h"
  15. #include "mintlib.h"
  16. #include "olga.h"
  17. #include "rsc.h"
  18. #include "scroll.h"
  19. #include "text.h"
  20. #include "file.h"
  21.  
  22. /* Puffer-Längen zum Lesen */
  23. #define    READBUFFSIZE    4*1024L
  24.  
  25. /*
  26.  * Bei Speichermangel ein Puffer, der eine Zeile plus
  27.  * Zeilenende aufnehmen kann (Lesen und Schreiben).
  28.  */
  29. #define STATICBUFFSIZE    MAX_LINE_LEN + 3
  30. LOCAL UBYTE    static_buffer[STATICBUFFSIZE];
  31.  
  32.  
  33. GLOBAL WORD    load(TEXTP t_ptr, BOOLEAN quiet)
  34. {
  35.     WORD    antw;
  36.  
  37.     antw = load_datei(t_ptr->filename, &t_ptr->text, TRUE, &t_ptr->ending);
  38.     t_ptr->cursor_line = t_ptr->text.head.nachf;
  39.     t_ptr->readonly = file_readonly(t_ptr->filename);
  40.     if (antw==0)
  41.     {
  42.         t_ptr->file_date_time = file_time(t_ptr->filename,NULL,NULL);
  43.     }
  44.     else
  45.         t_ptr->file_date_time = -1L;
  46.     if (antw!=0 && !quiet)
  47.     {
  48.         FILENAME    datei;
  49.         PATH    path;
  50.  
  51.         file_splitt(t_ptr->filename, path, datei);
  52.  
  53.         if (antw==-33 && path_exist(path))    /* file not found und Pfad existiert */
  54.             snote(1, NOTEXIST, datei);
  55.         else
  56.             snote(1, READERR, datei);
  57.     }
  58.     return(antw);
  59. }
  60.  
  61.  
  62. GLOBAL WORD load_datei(UBYTE *name, RINGP t, BOOLEAN verbose, LineEnding *end)
  63. {
  64.     WORD    fd, antw;
  65.  
  66.     Busy_mouse();
  67.     fd = (short) Fopen(name, 0);
  68.     if (fd > 0)
  69.     {
  70.         LONG        file_size;
  71.  
  72.         /* größe der Datei ermitteln */
  73.         file_size = Fseek(0, fd, 2);
  74.         Fseek(0, fd, 0);
  75.  
  76.         if (file_size >= 0L)
  77.         {
  78.             /* nicht schön, aber wirksam */
  79.             if ((LONG)Malloc(-1L) > file_size)
  80.             {
  81.                 UBYTE        *buffer, zeile[MAX_LINE_LEN + 3];    /* +2 für Zeilenende! */
  82.                 LINEP     start, next;
  83.                 LONG        buf_size, l, p, bytes;
  84.                 WORD        n;
  85.                 BOOLEAN    new_line, cr = FALSE;
  86.  
  87.                 /* Progress-Bar */
  88.                 verbose = verbose && ((file_size >> 10) >= transfer_size);
  89.                 if (verbose)
  90.                 {
  91.                     UBYTE        str[40];
  92.                     FILENAME    file;
  93.  
  94.                     strcpy(str, STRING(LOADSTR));
  95.                     file_name(name, file, FALSE);
  96.                     strcat(str, file);
  97.                     start_aktion(str, FALSE, file_size);
  98.                     bytes = 0L;
  99.                 }
  100.  
  101.                 /* Puffer anfordern */
  102.                 buf_size = min(READBUFFSIZE, file_size);
  103.                 buffer = (UBYTE *)Malloc(buf_size + 1);
  104.  
  105.                 if (buffer == NULL)
  106.                 {
  107.                     buffer = static_buffer;
  108.                     buf_size = STATICBUFFSIZE;
  109.                 }
  110.  
  111.                 /* Liste vorbereiten */
  112.                 start = t->tail.vorg;
  113.  
  114.                 /* Einlesen */
  115.                 l = Fread(fd, buf_size, buffer);
  116.                 buffer[l] = EOS;
  117.  
  118.                 strcpy(zeile, "");
  119.                 n = 0;
  120.                 new_line = FALSE;
  121.                 while (l > 0)
  122.                 {
  123.                     p = 0;
  124.                     while (p < l)
  125.                     {
  126.                         if (buffer[p] == 0x0D)                /* CR -> Mac */
  127.                         {
  128.                             new_line = TRUE;
  129.                             p++;
  130.                             cr = TRUE;
  131.                             *end = apple;
  132.                         }
  133.                         else if (buffer[p] == 0x0A)        /* LF */
  134.                         {
  135.                             p++;
  136.                             if (cr)                                /* CRLF -> TOS*/
  137.                             {
  138.                                 cr = FALSE;
  139.                                 *end = tos;
  140.                             }
  141.                             else
  142.                             {
  143.                                 new_line = TRUE;                /* -> Unix */
  144.                                 *end = unix;
  145.                             }
  146.                         }
  147.                         else if (n >= MAX_LINE_LEN)        /* Überlänge */
  148.                             new_line = TRUE;
  149.                         else
  150.                         {
  151.                             zeile[n] = buffer[p];
  152.                             n++;
  153.                             p++;
  154.                         }
  155.  
  156.                         if (new_line)
  157.                         {
  158.                             zeile[n] = EOS;
  159.                             start = start->nachf = new_col_w(zeile, n);
  160.                             n = 0;
  161.                             new_line = FALSE;
  162.                         }
  163.                     } /* while */
  164.                     if (verbose)
  165.                     {
  166.                         bytes += buf_size;
  167.                         do_aktion(bytes);
  168.                     }
  169.                     l = Fread(fd, buf_size, buffer);
  170.  
  171.                     /* EOF */
  172.                     if (l == 0)
  173.                     {
  174.                         /* letzte Zeile ohne Zeilenende! */
  175.                         if (n > 0)
  176.                         {
  177.                             zeile[n] = EOS;
  178.                             start = start->nachf = new_col_w(zeile, n);
  179.                         }
  180.  
  181.                         /* letzte Zeile hatte ZE -> ein Dummyzeile anhängen */
  182.                         else if (n == 0)
  183.                             start = start->nachf = new_col_b("", 0);
  184.                     }
  185.                 } /* while */
  186.  
  187.                 if (buffer != static_buffer)
  188.                     Mfree(buffer);
  189.  
  190.                 /* Ring schließen */
  191.                 t->tail.vorg = start;
  192.                 start->nachf = &t->tail;
  193.  
  194.                 /* Anzahl der Zeilen ermitteln */
  195.                 start = t->head.nachf;
  196.                 next = start->nachf;
  197.                 for (l = 0; !IS_TAIL(start); l++)
  198.                 {
  199.                     next->vorg = start;
  200.                     start = next;
  201.                     NEXT(next);
  202.                 }
  203.                 if (l > 1L)
  204.                 {
  205.                     col_delete(t->head.nachf);
  206.                     l--;
  207.                 }
  208.                 t->lines = l;
  209.  
  210.                 if (verbose)
  211.                     end_aktion();
  212.                 antw = 0;
  213.             }
  214.             else
  215.             {
  216.                 note(1, NOMEMORY);
  217.                 antw = -39;
  218.             }
  219.             Fclose(fd);
  220.         }
  221.         else
  222.             antw = -1;
  223.     }
  224.     else
  225.         antw = fd;
  226.     Last_mouse();
  227.     return(antw);
  228. }
  229.  
  230.  
  231. /*
  232.  * Ermittelt die anzahl der Bytes und Zeilen der übergebenen Datei.
  233.  * Wird bei der Projektverwaltung (Info) benutzt.
  234.  */
  235. GLOBAL WORD infoload(UBYTE *name, LONG *bytes, LONG *lines)
  236. {
  237.     RING            t;
  238.     WORD            antw;
  239.     LineEnding    ending;
  240.  
  241.     init_textring(&t);
  242.     if (load_datei(name, &t, FALSE, &ending) == 0)
  243.     {
  244.         *bytes = textring_bytes(&t, ending);
  245.         *lines = t.lines;
  246.         antw = 0;
  247.     }
  248.     else
  249.         antw = 1;
  250.     kill_textring(&t);
  251.     return antw;
  252. }
  253.  
  254.  
  255. /****************************************************************************/
  256.  
  257. LONG    VOID backup_name(UBYTE *name, UBYTE *ext)
  258. {
  259.     PATH    new;
  260.  
  261.     strcpy(new, name);
  262.     strcat(new, ".");
  263.     strcat(new, ext);
  264.     if (longName(new) >= strlen(new))
  265.         strcpy(name, new);
  266.     else
  267.         make_ext(name, ext);
  268. }
  269.  
  270. LOCAL VOID restore_back_up(TEXTP t_ptr)
  271. {
  272.     if (t_ptr->loc_opt->backup)
  273.     {
  274.         PATH old;
  275.  
  276.         if (file_exist(t_ptr->filename))
  277.             Fdelete(t_ptr->filename);
  278.         strcpy(old, t_ptr->filename);
  279.         backup_name(old, t_ptr->loc_opt->backup_ext);
  280.         Frename(0, old, t_ptr->filename);
  281.     }
  282. }
  283.  
  284.  
  285. LOCAL VOID back_up(TEXTP t_ptr)
  286. {
  287.     PATH new;
  288.  
  289.     if (t_ptr->loc_opt->backup)
  290.     {
  291.         Busy_mouse();
  292.         strcpy(new, t_ptr->filename);
  293.         backup_name(new, t_ptr->loc_opt->backup_ext);
  294.         if (file_exist(new))            /* Alte DUP-Datei löschen */
  295.             Fdelete(new);
  296.         Frename(0, t_ptr->filename, new);
  297.         Last_mouse();
  298.     }
  299. }
  300.  
  301.  
  302. GLOBAL WORD save_datei(UBYTE *name, RINGP t, BOOLEAN verbose, LineEnding ending)
  303. {
  304.     WORD    fd, antw;
  305.  
  306.     Busy_mouse();
  307.     fd = (short) Fcreate(name, 0);
  308.     if (fd > 0)
  309.     {
  310.         UBYTE        *buffer, end_str[3], zeile[MAX_LINE_LEN + 3], *ptr;
  311.         WORD        z_len;
  312.         LONG        buf_size, text_size, b, ret, rest, count;
  313.         LINEP        lauf;
  314.  
  315.         /* Puffer anfordern */
  316.         text_size = textring_bytes(t, ending);
  317.         buffer = (UBYTE *)Malloc(text_size + 1);
  318.         if (buffer == NULL)
  319.         {
  320.             buffer = static_buffer;
  321.             buf_size = STATICBUFFSIZE;
  322.         }
  323.         else
  324.             buf_size = text_size;
  325.  
  326.         buffer[0] = EOS;
  327.  
  328.         /* Progress-Bar */
  329.         verbose = verbose && ((text_size >> 10) >= transfer_size);
  330.         if (verbose)
  331.         {
  332.             UBYTE    str[40];
  333.             FILENAME    file;
  334.  
  335.             strcpy(str, STRING(SAVESTR));
  336.             file_name(name, file, FALSE);
  337.             strcat(str,file);
  338.             start_aktion(str, FALSE, t->lines);
  339.             count = 0L;
  340.         }
  341.  
  342.         /* String mit Zeilenende erzeugen */
  343.         switch (ending)
  344.         {
  345.             case tos :
  346.                 strcpy(end_str, "\r\n");
  347.                 break;
  348.             case unix :
  349.                 strcpy(end_str, "\n");
  350.                 break;
  351.             case apple :
  352.                 strcpy(end_str, "\r");
  353.                 break;
  354.             default:
  355.                 strcpy(end_str, "");
  356.                 break;
  357.         }
  358.  
  359.         /* Text im Puffer    verketten und wegschreiben */
  360.         lauf = FIRST(t);
  361.         if (lauf != NULL)
  362.         {
  363.             b = 0L;
  364.             ret = 1;
  365.             ptr = buffer;
  366.             rest = buf_size;
  367.             while ((!IS_TAIL(lauf)) && (ret > 0))
  368.             {
  369.                 /* Zeile aus Text und Zeilenende zusammen setzen */
  370.  
  371.                 strcpy(zeile, TEXT(lauf));
  372.  
  373.                 /*
  374.                  * Das Zeilenende wird nur dann angehängt, wenn lauf nicht letzte
  375.                  * Zeile ist. Gab es beim Laden der Datei in der letzten Zeile
  376.                  * ein ZE, gibt es die Dummyzeile. Gab es das ZE nicht, wird auch
  377.                  * kein ZE angehängt!
  378.                  */
  379.                 if (!IS_LAST(lauf))
  380.                     strcat(zeile, end_str);
  381.  
  382.                 z_len = (short)strlen(zeile);
  383.  
  384.                 /* Passt die Zeile noch in den Puffer? */
  385.                 if (z_len < rest)
  386.                 {
  387.                     /* komplett in den Puffer */
  388.                     ptr = COPYB(ptr, zeile, z_len);
  389.                     b += z_len;
  390.                     rest -= z_len;
  391.                 }
  392.                 else
  393.                 {
  394.                     /* nur soviel kopieren, wie noch passt */
  395.                     ptr = COPYB(ptr, zeile, (short)rest);
  396.  
  397.                     /* wegschreiben */
  398.                     ret = Fwrite(fd, buf_size, buffer);
  399.  
  400.                     if (ret != buf_size)
  401.                         ret = -ENOSPC;
  402.  
  403.                     /* und den Rest in den Puffer */
  404.                     b = z_len - rest;
  405.                     ptr = COPYB(buffer, zeile+rest, (short)b);
  406.                     rest = buf_size - b;
  407.                 }
  408.                 if (verbose)
  409.                 {
  410.                     count++;
  411.                     do_aktion(count);
  412.                 }
  413.                 NEXT(lauf);
  414.             }
  415.  
  416.             /* Befindet sich noch etwas im Puffer und ist kein Fehler aufgetreten? */
  417.             if ((b > 0L) && (ret > 0))
  418.             {
  419.                 ret = Fwrite(fd, b, buffer);
  420.                 if (ret != buf_size)
  421.                     ret = -ENOSPC;
  422.             }
  423.             if (ret < 0)
  424.                 antw = (short)ret;
  425.             else
  426.                 antw = 0;
  427.         }
  428.         else
  429.             antw = 1;
  430.  
  431.         Fclose(fd);
  432.         if (antw == -ENOSPC)
  433.             Fdelete(name);
  434.  
  435.         if (buffer != static_buffer)
  436.             Mfree(buffer);
  437.  
  438.         if (verbose)
  439.             end_aktion();
  440.     }
  441.     else
  442.         antw = fd;
  443.  
  444.     Last_mouse();
  445.     return antw;
  446. }
  447.  
  448.  
  449. GLOBAL WORD save(TEXTP t_ptr)
  450. {
  451.     WORD    antw;
  452.  
  453.     if (file_exist(t_ptr->filename))
  454.     {
  455.         if (file_readonly(t_ptr->filename))
  456.         {
  457.             FILENAME    file;
  458.  
  459.             t_ptr->readonly = TRUE;
  460.             file_name(t_ptr->filename, file, FALSE);
  461.             snote(1, READONLY, file);
  462.             return -39;
  463.         }
  464.         else
  465.             t_ptr->readonly = FALSE;
  466.         if (t_ptr->file_date_time != -1L)
  467.         {
  468.             LONG date_time = file_time(t_ptr->filename, NULL, NULL);
  469.  
  470.             if (date_time != t_ptr->file_date_time)
  471.             {
  472.                 FILENAME    name;
  473.  
  474.                 file_name(t_ptr->filename, name, FALSE);
  475.                 if (snote(1, MOVED2, name) == 2)
  476.                     return -1;
  477.             }
  478.         }
  479.     }
  480.     back_up(t_ptr);
  481.     antw = save_datei(t_ptr->filename, &t_ptr->text, TRUE, t_ptr->ending);
  482.     if (antw == 0)
  483.     {
  484.         t_ptr->moved = 0;
  485.         t_ptr->file_date_time = file_time(t_ptr->filename, NULL, NULL);
  486.         t_ptr->count = local_time->tm_min;
  487.  
  488.         /* OLGA informieren */
  489.         do_OLGA(OLGA_UPDATE, t_ptr->filename, NULL);
  490.     }
  491.     else
  492.     {
  493.         if (antw == -ENOSPC)
  494.         {
  495.             UBYTE    tmp[20];
  496.  
  497.             make_shortpath(t_ptr->filename, tmp, 19);
  498.             snote(1, NOSPACE, tmp);
  499.         }
  500.         else
  501.             note(1, WRITEERR);
  502. /*        restore_back_up(t_ptr); */
  503.         t_ptr->file_date_time = -1L;
  504.     }
  505.  
  506.     return antw;
  507. }
  508.  
  509.  
  510. GLOBAL WORD save_as(TEXTP t_ptr, UBYTE *name)
  511. {
  512.     WORD    antw;
  513.  
  514.     if (file_exist(name))
  515.     {
  516.         if (file_readonly(name))
  517.         {
  518.             FILENAME    file;
  519.  
  520.             file_name(t_ptr->filename, file, FALSE);
  521.             snote(1,READONLY, file);
  522.             return -39;
  523.         }
  524.     }
  525.     antw = save_datei(name, &t_ptr->text, TRUE, t_ptr->ending);
  526.     if (antw != 0)
  527.     {
  528.         if (antw == -ENOSPC)
  529.         {
  530.             UBYTE    tmp[20];
  531.  
  532.             make_shortpath(t_ptr->filename, tmp, 19);
  533.             snote(1, NOSPACE, tmp);
  534.         }
  535.         else
  536.             note(1, WRITEERR);
  537. /*        restore_back_up(t_ptr);*/
  538.     }
  539.     return(antw);
  540. }
  541.  
  542.  
  543. GLOBAL BOOLEAN    save_new(UBYTE *name, FSEL *fsel, UBYTE *text)
  544. {
  545.     fsel->name[0] = EOS;
  546.     if (!select_file(fsel,name, text))
  547.         return FALSE;
  548.     if (file_exist(name))
  549.     {
  550.         if (note(1,EXIST)==2) return
  551.             FALSE;
  552.     }
  553.     return TRUE;
  554. }
  555.